
#include <iostream>
#include <unistd.h>
#include <memory>
#include <fstream>

#include "TcpServer.hpp"
#include "HttpProtocol.hpp"

using namespace std;
using namespace Network;

string GetFileContent(string path)
{
    // ifstream in(path, ios::in | ios::binary);
    // if (!in.is_open())
    //     return "";

    // string content;
    // in >> content;
    // in.close();
    // return content;

    ifstream in(path, ios::in | ios::binary);
    if(!in.is_open()) return "";

    in.seekg(0, in.end);
    int filesize = in.tellg();
    in.seekg(0, in.beg);

    string content;
    content.resize(filesize);
    in.read((char*)content.c_str(),filesize);

    // vector<char> content(filesize);
    // in.read(content.data(), filesize);
    
    in.close();
    return content;
}

string SuffixToContentType(const string& suffix)
{
    if(suffix==".html")
        return "text/html";
    else if(suffix==".png")
        return "image/png";
    else if(suffix==".jpg")
        return "image/jpeg";
    else return "text/html";
}

// 网络负责IO发送
// HandlerHttpRequest字节流数据解析和调用业务处理方法
// 处理报文的方法
// 我们认为我们已经读到了一个完整请求
string HandlerHttpRequest(string &request)
{

    HttpRequest req;

    // 反序列化
    req.Deserialize(request);

    // 解析URL
    req.Parse();
    req.Debug();

    string content;
    content = GetFileContent(req.GetPath());
    //cout<<"content: "<<content<<endl;

    if (!content.empty())
    {

        string httpstatusline = "HTTP/1.1 200 OK\r\n";
        string httpheader = "Content-Length: " + to_string(content.size()) + "\r\n";
        httpheader+= "Content-Type: "+SuffixToContentType(req.GetSuffix())+"\r\n";
        httpheader += "\r\n";

        string httpresponse = httpstatusline + httpheader + content;
        return httpresponse;
    }

    return "";
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Usage:\n     ./udp_echo_server <port>" << endl;
        return 0;
    }

    uint16_t localport = stoi(argv[1]);

    unique_ptr<TcpServer> svr(new TcpServer(localport, HandlerHttpRequest));
    svr->Loop();
    return 0;
}
